﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Data.SqlServerCe;
using System.Collections;
using System.Resources;
using System.Xml;
using System.Xml.Linq;
using System.Threading;
using System.Globalization;

namespace RCSnake
	{
	public partial class FormMain : Form
		{
		/*---------------------------------------------*\
		|*                 Attributs                   *|
		\*---------------------------------------------*/
		private Snake m_snake;
		private bool m_isStarted;
		private System.Windows.Forms.Timer m_timer; //utilisé pour faire bouger le serpent avec un certain temps
		private Border m_border; // La bordure de l'arène
		private Area m_area; //C'est ici que le serpent mange et grandit
		private bool m_createBigFood; //Utilisé lorsque le serpent mange la petite nourriture. Après x petit, un grand est accessible
		private bool m_canBePressed; //A chaque laps de temps où le serpent bouge, les touches ne sont pas disponibles
		private FormResults m_windowResult; //Fenêtre faisant appel à la base de données des scores et les affichant
		private FormAbout m_windowAbout;
		private FormConfig m_windowKeyboard; //Fenêtre pour configurer les touches
		private Random m_random; //Utilisé pour changer l'emplacement de la nourriture
		private int m_cptTimerPercentage; //Affiche le pourcentage de la vitesse
		private bool m_isHandlingBigFood; //Astuce permettant de faire fonctionner correctement le slot bigFoodEaten. Pour des raisons inconnu lorsque le serpent mange la grosse nourriture, plusieurs sont comptabilisées !? Cette variable évite cela
		private Thread m_threadBigFood; //thread permettant de lancer un timer et de faire disparaitre la grosse nourriture à la fin si le serpent ne la pas manger.
		private bool m_isThreadBigFoodCreated; //Permet de ne créer qu'une seule fois le thread
		private ResourceManager m_resourceManager = null;
		private CultureInfo m_englishCulture = new CultureInfo("en-US");
		private CultureInfo m_frenchCulture = new CultureInfo("fr-FR");
		private CultureInfo m_spanishCulture = new CultureInfo("es-ES");
		/*---------------------------------------------*\
		|*                Constructeur                 *|
		\*---------------------------------------------*/
		/// <summary>
		/// 
		/// </summary>
		public FormMain()
			{
			InitializeComponent();
			actionEnglish.Checked = true;
			m_createBigFood = false;
			m_border = new Border(new Point(20, 200), new Size(Parameters.DEFAULT_BORDER_SIZE, Parameters.DEFAULT_BORDER_SIZE));
			m_area = new Area(m_border);
			m_random = new Random();

			Size size = new Size(Parameters.DEFAULT_SNAKE_SIZE, Parameters.DEFAULT_SNAKE_SIZE);
			Point startPosition = new Point(Parameters.DEFAULT_POSX_START, Parameters.DEFAULT_POSY_START);
			m_snake = new Snake(m_area, size, startPosition);

			m_isStarted = false;

			m_timer = new System.Windows.Forms.Timer();
			m_timer.Interval = Parameters.DEFAULT_INTERVAL;
			m_timer.Enabled = true;
			m_timer.Tick += new EventHandler(onTimeEvent);
			m_canBePressed = false;
			m_cptTimerPercentage = 1;

			m_snake.signal_clashed += new Snake.clashEventHandler(slot_clashed);
			m_snake.signal_smallFoodEaten += new Snake.eatEventHandler(slot_smallFoodEaten);
			m_snake.signal_bigFoodEaten += new Snake.eatEventHandler(slot_bigFoodEaten);

			m_area.smallFood = new SmallFood(m_area, new Size(Parameters.DEFAULT_SMALLFOOD_SIZE, Parameters.DEFAULT_SMALLFOOD_SIZE), new Point());
			m_area.smallFood.exists = true;
			m_area.bigFood = new BigFood(m_area, new Size(Parameters.DEFAULT_BIGFOOD_SIZE, Parameters.DEFAULT_BIGFOOD_SIZE), new Point());

			m_windowAbout = new FormAbout();
			m_windowKeyboard = new FormConfig();
			m_isHandlingBigFood = false;
			this.BackgroundImage = Image.FromHbitmap(Properties.Resources.background.GetHbitmap());

			m_threadBigFood = new Thread(new ThreadStart(fctBigFoodWaiting));
			m_isThreadBigFoodCreated = false;

			//Cette ligne permet de créer un double buffer pour améliorer les peformances d'affichage et éviter les scintillements d'écran
			this.SetStyle(ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint | ControlStyles.DoubleBuffer, true);
			}

		/*---------------------------------------------*\
		|*               Methodes public               *|
		\*---------------------------------------------*/

		/*---------------------*\
		|*      get / set      *|
		\*---------------------*/
		/// <summary>
		/// 
		/// </summary>
		public bool isStarted
			{
			get { return m_isStarted; }
			set { m_isStarted = value; }
			}



		/*---------------------------------------------*\
		|*              Methodes private               *|
		\*---------------------------------------------*/

		/// <summary>
		/// Cette fonction permet de diminuer l'interval de temps du timer permettant au serpent d'aller plus vite à chaque fois.
		/// Une fois que l'interval atteint au moins la valeur correspondant au pas de décrémentation, elle n'est plus utilisée
		/// </summary>
		private void decrementTimerInterval()
			{
			if(m_timer.Interval > Parameters.DEFAULT_DEC_TIMER_STEP)
				{
				m_cptTimerPercentage++;
				m_timer.Interval -= Parameters.DEFAULT_DEC_TIMER_STEP;
				this.numSpeedPercentage.Value = Convert.ToDecimal(m_cptTimerPercentage / (Parameters.DEFAULT_TOTAL_INTERVAL) * 100);
				this.lblSpeedPercentage.Text = this.numSpeedPercentage.Value.ToString("F1") + " %";
				}
			}

		private void reset()
			{
			this.numBigFood.Value = 0;
			this.numLength.Value = 0;
			this.numPoints.Value = 0;
			this.numSmallFood.Value = 0;
			this.lblPoints.Text = this.numPoints.Value.ToString();
			this.lblLength.Text = this.numLength.Value.ToString();
			this.lblBigFood.Text = this.numBigFood.Value.ToString();
			this.lblSmallFood.Text = this.numSmallFood.Value.ToString();
			this.lblSpeedPercentage.Text = "0.0 %";
			this.m_isHandlingBigFood = false;
			this.m_area.bigFood.exists = false;
			this.m_createBigFood = false;
			m_cptTimerPercentage = 1;
			this.numSpeedPercentage.Value = 0;
			this.lblLength.Text = m_snake.listBodyBlocks.Count().ToString();
			m_timer.Interval = Parameters.DEFAULT_INTERVAL;
			m_threadBigFood.Abort();
			m_isThreadBigFoodCreated = false;
			}


		private void initLanguage()
			{
			this.Location = Properties.Settings.Default.windowPosition;
			String language = Properties.Settings.Default.language;
			if(language == actionFrench.Text)
				{
				actionFrench.Checked = true;
				actionEnglish.Checked = false;
				actionSpanish.Checked = false;
				Thread.CurrentThread.CurrentUICulture = m_frenchCulture;
				}
			else if(language == actionSpanish.Text)
				{
				actionSpanish.Checked = true;
				actionEnglish.Checked = false;
				actionFrench.Checked = false;
				Thread.CurrentThread.CurrentUICulture = m_spanishCulture;
				}
			else
				{
				actionEnglish.Checked = true;
				actionFrench.Checked = false;
				actionSpanish.Checked = false;
				Thread.CurrentThread.CurrentUICulture = m_englishCulture;
				}
			putText();
			}

		private void putText()
			{
			menuFile.Text = m_resourceManager.GetString("menuFile");
			menuSettings.Text = m_resourceManager.GetString("menuSettings");
			menuScores.Text = m_resourceManager.GetString("menuScores");
			menuHelp.Text = m_resourceManager.GetString("menuHelp");
			actionAbout.Text = m_resourceManager.GetString("actionAbout");
			actionEnglish.Text = m_resourceManager.GetString("actionEnglish");
			actionExit.Text = m_resourceManager.GetString("actionExit");
			actionFrench.Text = m_resourceManager.GetString("actionFrench");
			actionKeyboard.Text = m_resourceManager.GetString("actionKeys");
			actionReset.Text = m_resourceManager.GetString("actionReset");
			actionHelp.Text = m_resourceManager.GetString("actionHelp");
			actionStart.Text = m_resourceManager.GetString("actionStart");
			actionView.Text = m_resourceManager.GetString("actionView");
			menuLanguage.Text = m_resourceManager.GetString("menuLanguage");
			lblBigFoodName.Text = m_resourceManager.GetString("labelBigFood");
			lblLengthName.Text = m_resourceManager.GetString("labelLength");
			lblPointsName.Text = m_resourceManager.GetString("labelPoints");
			lblSmallEatenName.Text = m_resourceManager.GetString("labelSmallFood");
			lblSpeedName.Text = m_resourceManager.GetString("labelSpeed");


			Update();
			Refresh();
			}

		//Méthode utilisé par le thread de BigFood permettant d'utiliser un timer en arrière plan déterminer le temps que la grosse nourriture reste accessible
		private void fctBigFoodWaiting()
			{
			Thread.Sleep(Parameters.DEFAULT_BIGFOOD_TIME_APPEAR);
			}
		/*---------------------*\
		|*         slot        *|
		\*---------------------*/

		private void MainWindow_Load(object sender, EventArgs e)
			{
			m_resourceManager = new ResourceManager("RCSnake.FormMain", typeof(FormMain).Assembly);
			foreach(Control ctrl in this.Controls)
				{
				ctrl.KeyDown += new KeyEventHandler(MainWindow_KeyDown);
				}

			initLanguage();
			}


		/// <summary>
		/// Cette méthode correspond à crash du serpent sur un mur ou sur lui-même.
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		private void slot_clashed(object sender, SnakeEventArgs e)
			{
			this.actionStart.Text = "Start";
			this.actionStart.Image = Image.FromHbitmap(Properties.Resources.start.GetHbitmap());
			m_isStarted = false;
			m_windowResult = new FormResults(Convert.ToInt32(this.numPoints.Value), Convert.ToInt32(this.numLength.Value));
			m_windowResult.ShowDialog();
			this.actionView.PerformClick();
			m_snake.reset();
			this.reset();
			this.Refresh();
			this.Update();
			}

		/// <summary>
		/// Cette méthode permet de comptabiliser le nombre de petite nourriture.
		/// Après x, la gros nourriture est rendu accessible.
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		private void slot_smallFoodEaten(object sender, SnakeEventArgs e)
			{
			m_area.smallFood.exists = false;
			m_snake.incrementSmallFood();

			for(int i = 0 ; i < m_area.smallFood.enlargement ; ++i)
				{
				m_snake.grow();
				}

			this.decrementTimerInterval();
			this.numPoints.Value += Parameters.DEFAULT_SMALLFOOD_POINTS;
			this.numLength.Value = m_snake.listBodyBlocks.Count;
			this.numSmallFood.Value = m_snake.nbSmallFoodEaten;
			this.lblPoints.Text = this.numPoints.Value.ToString();
			this.lblLength.Text = this.numLength.Value.ToString();
			this.lblSmallFood.Text = this.numSmallFood.Value.ToString();

			if(m_snake.nbSmallFoodEaten % Parameters.DEFAULT_NB_SMALLFOOD == 0 && m_snake.nbSmallFoodEaten != 0)
				{
				m_createBigFood = true;
				}

			m_area.smallFood.changePosition();
			m_area.smallFood.exists = true;
			}

		private void slot_bigFoodEaten(object sender, SnakeEventArgs e)
			{
			if(!m_isHandlingBigFood)
				{
				m_isHandlingBigFood = true;
				m_area.bigFood.exists = false;
				m_snake.incrementBigFood();

				for(int i = 0 ; i < m_area.bigFood.enlargement ; ++i)
					{
					m_snake.grow();
					}

				this.decrementTimerInterval();
				this.numPoints.Value += Parameters.DEFAULT_BIGFOOD_POINTS;
				this.numLength.Value = m_snake.listBodyBlocks.Count;
				this.numBigFood.Value = m_snake.nbBigFoodEaten;
				this.lblPoints.Text = this.numPoints.Value.ToString();
				this.lblLength.Text = this.numLength.Value.ToString();
				this.lblBigFood.Text = this.numBigFood.Value.ToString();
				}
			}

		private void onTimeEvent(object sender, EventArgs e)
			{
			m_canBePressed = false;
			if(m_isStarted)
				{
				m_snake.move();
				m_snake.testClash();
				m_snake.testEat();
				this.Refresh();
				this.Update();
				this.numLength.Value = m_snake.listBodyBlocks.Count;
				}
			m_canBePressed = true;
			}

		private void MainWindow_Paint(object sender, PaintEventArgs e)
			{
			//Rendu de la bordure de l'arène
			m_border.draw(e);

			//Rendu du serpent en entier
			foreach(BodyBlock body in m_snake.listBodyBlocks)
				{
				body.draw(e);
				}

			//La grosse nourriture est rendu accessible
			if(m_createBigFood)
				{
				m_createBigFood = false;
				m_area.bigFood.changePosition();
				m_area.bigFood.exists = true;
				m_isHandlingBigFood = false;
				m_isThreadBigFoodCreated = false;
				m_threadBigFood = new Thread(new ThreadStart(fctBigFoodWaiting));
				}

			//On dessine la petite nourriture quand elle existe
			if(m_area.smallFood.exists)
				{
				m_area.smallFood.draw(e);
				}

			//Si la grosse nouriture existe, on lance le thread. La grosse nourriture disparait si le serpent mange ou si le temps est écoulé
			if(m_area.bigFood.exists)
				{
				if(!m_isThreadBigFoodCreated)
					{
					m_isThreadBigFoodCreated = true;
					m_threadBigFood.Start();
					}

				if(m_threadBigFood.IsAlive)
					{
					m_area.bigFood.draw(e);
					}
				else
					{
					m_threadBigFood.Abort();
					m_area.bigFood.exists = false;
					}
				}
			}

		private void exitToolStripMenuItem_Click(object sender, EventArgs e)
			{
			this.Close();
			}

		private void aboutToolStripMenuItem_Click(object sender, EventArgs e)
			{
			m_windowAbout.ShowDialog();
			}

		//Bouton start. Ce dernier devient Stop après clique. Stop redevient Start après accident du serpent
		private void startToolStripMenuItem_Click(object sender, EventArgs e)
			{
			if(!m_isStarted)
				{
				m_timer.Start();
				m_isStarted = true;
				this.actionStart.Text = "Stop";
				this.actionStart.Image = Image.FromHbitmap(Properties.Resources.Stop.GetHbitmap());
				}
			else
				{
				SnakeEventArgs f = new SnakeEventArgs();
				this.slot_clashed(this, f);
				}
			}

		/// <summary>
		/// Permet de gérer l'orientation du serpent
		/// Ne fonctionne que si le programme ne se trouve pas dans un interval de temps du timer.
		/// Cela est déterminé grâce à la variable canBePressed
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		private void MainWindow_KeyDown(object sender, KeyEventArgs e)
			{
			//Si la touche droite a été appuyée
			if(e.KeyCode.ToString().Equals(m_windowKeyboard.right) && m_canBePressed)
				{
				//Si le serpent ne va pas à gauche (sens contraire), il peut tourner
				if(m_snake.directionX != (int)Direction.NEGATIVE)
					{
					m_snake.directionX = (int)Direction.POSITIVE;
					m_snake.directionY = (int)Direction.NULL;
					}
				}
			else if(e.KeyCode.ToString().Equals(m_windowKeyboard.left) && m_canBePressed)
				{
				if(m_snake.directionX != (int)Direction.POSITIVE)
					{
					m_snake.directionX = (int)Direction.NEGATIVE;
					m_snake.directionY = (int)Direction.NULL;
					}
				}
			else if(e.KeyCode.ToString().Equals(m_windowKeyboard.up) && m_canBePressed)
				{
				if(m_snake.directionY != (int)Direction.POSITIVE)
					{
					m_snake.directionY = (int)Direction.NEGATIVE;
					m_snake.directionX = (int)Direction.NULL;
					}
				}
			else if(e.KeyCode.ToString().Equals(m_windowKeyboard.down) && m_canBePressed)
				{
				if(m_snake.directionY != (int)Direction.NEGATIVE)
					{
					m_snake.directionY = (int)Direction.POSITIVE;
					m_snake.directionX = (int)Direction.NULL;
					}
				}
			}

		/// <summary>
		/// Affichage des scores de la BDD
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		private void scoresToolStripMenuItem_Click(object sender, EventArgs e)
			{
			SqlCeConnectionSecure sqlConnection = new SqlCeConnectionSecure(Parameters.DEFAULT_DATABASE_NAME);

			try
				{
				SqlCeCommand cmd = new SqlCeCommand();
				cmd.Connection = sqlConnection.connection;
				cmd.CommandText = "select top(" + Parameters.DEFAULT_NB_SCORE + ") * from Score order by points desc";
				DataSet ds = new DataSet();
				SqlCeDataAdapter da = new SqlCeDataAdapter();
				da.SelectCommand = cmd;
				da.Fill(ds, "Score");
				DataTable table = ds.Tables["Score"];

				table.DefaultView.Sort = "points DESC,length ASC,name ASC";


				String str = "";

				int i = 0;
				str += "(" + m_resourceManager.GetString("scoresRank") + ")\t" + m_resourceManager.GetString("scoresName") + "\t:\t" + m_resourceManager.GetString("scoresValue") + "\t-\t[" + m_resourceManager.GetString("scoresLength") + "]\n";
				str += "\n";
				foreach(DataRowView line in table.DefaultView)
					{
					++i;
					str += "(" + i.ToString() + ")\t" + line["name"] + "\t:\t" + line["points"] + "\t-\t[" + line["length"] + "]\n";
					}

				MessageBox.Show(str, m_resourceManager.GetString("scoresTitle"), MessageBoxButtons.OK, MessageBoxIcon.Information);
				}
			catch(Exception f)
				{
				MessageBox.Show(f.ToString(), "SQL Select error", MessageBoxButtons.OK, MessageBoxIcon.Error);
				}
			}

		private void resetScoresToolStripMenuItem_Click(object sender, EventArgs e)
			{
			try
				{
				SqlCeConnectionSecure sqlConnection = new SqlCeConnectionSecure(Parameters.DEFAULT_DATABASE_NAME);

				SqlCeCommand cmd = new SqlCeCommand();
				cmd.Connection = sqlConnection.connection;
				cmd.CommandText = "select * from Score";
				DataSet ds = new DataSet();
				SqlCeDataAdapter da = new SqlCeDataAdapter();
				da.SelectCommand = cmd;
				da.Fill(ds, "Score");
				DataTable table = ds.Tables["Score"];

				int nbLines = table.Rows.Count;

				for(int i = 0 ; i < nbLines ; ++i)
					{
					table.Rows[i].Delete();
					}

				SqlCeCommandBuilder bldr = new SqlCeCommandBuilder(da);
				da.Update(table);
				}
			catch(Exception f)
				{
				MessageBox.Show(f.ToString(), "SQL Delete error", MessageBoxButtons.OK, MessageBoxIcon.Error);
				}
			}

		private void rulesToolStripMenuItem_Click(object sender, EventArgs e)
			{
			String str = "";

			if(actionFrench.Checked)
				{
				str += "[PARAMÈTRES]\n";
				str += "- Vous pouvez changer les touches de direction depuis le menu 'Paramètres' puis le bouton 'Touches', ou en utilisant le raccourci 'Ctrl-K'. Par défaut, les flèches sont utilisées.\n";
				str += "- La langue du programme peut être changée via le menu 'Paramètres' puis le menu 'Langue'.\n\n";
				str += "[COMMENT JOUER ?]\n";
				str += "- Cliquez sur le menu 'Fichier' puis sur le bouton 'Commencer', ou en utilisant le raccourci 'Ctrl-S', pour commencer une partie.\n";
				str += "- Pendant la partie, vous devrez manger un maximum de nourriture que vous verrez apparaître dans l'arène.\n";
				str += "- Vous pouvez vous dirigez vers les quatre points cardinaux à l'aide des touches que vous pouvez configurer dans le menu 'Paramètres'. Par défaut, les touches sont les flèches.\n";
				str += "- Vous devez essayer de tenir le plus longtemps possible sans toucher un mur ou vous-même, sans quoi la partie se termine\n";
				str += "- Quand la partie se termine, vous avez la possibilité de sauvegarder votre score ave votre nom. Ce dernier peut être vu par la suite en allant dans le menu 'Scores'\n\n";
				str += "[RÉSULTATS]\n";
				str += "- Vous pouvez voir les résultats de tout le monde en cliquant sur le menu 'Résultats' puis sur le bouton 'Voir', ou en utilisant le raccourci 'Ctrl-V'\n";
				str += "- Si vous souhaitez réinitialisez le tableau de résultat, cliquez sur le menu 'Résultats' puis sur le bouton 'Réinitialiser', ou à l'aide du raccourci 'Ctrl-R'.\n\n";
				str += "[NOURRITURE]\n";
				str += "- Il existe deux types de nourriture : la petite en vert, et la grosse en rouge.\nLa petite nourriture apparaît continuellement et vaut " + Parameters.DEFAULT_SMALLFOOD_POINTS + " points.\n";
				str += "La grosse nourriture, dont la valeur est " + Parameters.DEFAULT_BIGFOOD_POINTS + " points, n'apparaît seulement qu'après avoir manger " + Parameters.DEFAULT_NB_SMALLFOOD + " petites nourriture. Vous n'avez seulement que " + Parameters.DEFAULT_BIGFOOD_TIME_APPEAR / 1000 + " secondes pour essayer d'en manger une, après quoi elle disparaît.\n\n";
				}
			else
				{
				str += "[SETTINGS]\n";
				str += "- You can configure direction keys by clicking on 'Settings' menu then 'Keys' button, or with Ctrl-K shortcut keys. The arrows are used by default.\n";
				str += "- The language of this application can be changed by clicking on 'Settings' menu then 'Language' menu.\n\n";
				str += "[HOW TO PLAY ?]\n";
				str += "- Click on menu 'File' then button 'Start', or use 'Ctrl-S' shorcut keys, to begin to play.\n";
				str += "- During play, you need to eat a maximum of items that you will see in the \"arena\"\n";
				str += "- You can move in all directions(up, down, right, left) with the buttons that are configured in 'Keys' settings (the default keys are the arrows).\n";
				str += "- You should not touch the walls and yourself otherwise you end the game.\n";
				str += "- At the end, your can save your score with a name. Your scores can be seen in the scores menu.\n";
				str += "- You can at all times stop the current play by clicking on 'File' menu then 'Stop' button, or using 'Ctrl-S' shortcut keys.\n\n";
				str += "[SCORES]\n";
				str += "- You can see the saved scores by clicking on 'Scores' menu then 'view' button, or with 'Ctrl-V' shortcut keys.\n";
				str += "- If you wish to reset scores, click on 'Scores' menu then 'reset' button, or with 'Ctrl-R' shortcut keys.\n\n";
				str += "[FOOD]\n";
				str += "- There are two kinds of food : small in green and big in red.\nThe small food appears constantly and are worth " + Parameters.DEFAULT_SMALLFOOD_POINTS + " points.\n";
				str += "The big food, whose value is worth " + Parameters.DEFAULT_BIGFOOD_POINTS + " points, only appears after eating " + Parameters.DEFAULT_NB_SMALLFOOD + " small foods. You have only " + Parameters.DEFAULT_BIGFOOD_TIME_APPEAR / 1000 + " seconds to try eat one. After this time, the big food disapears.";

				}

			MessageBox.Show(this, str, m_resourceManager.GetString("helpTitle"), MessageBoxButtons.OK, MessageBoxIcon.Information);
			}

		private void keyboardToolStripMenuItem_Click(object sender, EventArgs e)
			{
			m_windowKeyboard.ShowDialog();
			}

		/// <summary>
		/// A la fermeture de l'application, les touches de direction sont sauvegardées dans un fichier XML
		/// Ce dernier est traité à l'aide de LINQ
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		private void FormMain_FormClosing(object sender, FormClosingEventArgs e)
			{
			m_windowKeyboard.saveKeyboardConfig();
			Properties.Settings.Default.windowPosition = this.Location;
			Properties.Settings.Default.language = actionEnglish.Checked ? actionEnglish.Text.Substring(1) : actionFrench.Text.Substring(1);
			Properties.Settings.Default.Save();
			}

		private void englishToolStripMenuItem_Click(object sender, EventArgs e)
			{
			System.Threading.Thread.CurrentThread.CurrentUICulture = m_englishCulture;
			actionFrench.Checked = false;
			actionSpanish.Checked = false;
			actionEnglish.Checked = true;
			putText();

			}

		private void frenchToolStripMenuItem_Click(object sender, EventArgs e)
			{
			System.Threading.Thread.CurrentThread.CurrentUICulture = m_frenchCulture;
			actionFrench.Checked = true;
			actionEnglish.Checked = false;
			actionSpanish.Checked = false;
			putText();
			}

		private void actionSpanish_Click(object sender, EventArgs e)
			{
			System.Threading.Thread.CurrentThread.CurrentUICulture = m_spanishCulture;
			actionFrench.Checked = false;
			actionEnglish.Checked = false;
			actionSpanish.Checked = true;
			putText();
			}
		}
	}
